home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume10 / comobj.lisp / part13 < prev    next >
Encoding:
Internet Message Format  |  1987-08-02  |  59.0 KB

  1. Path: uunet!rs
  2. From: rs@uunet.UU.NET (Rich Salz)
  3. Newsgroups: comp.sources.unix
  4. Subject: v10i087:  Common Loops, Common Objects, Common Lisp, Part13/13
  5. Message-ID: <758@uunet.UU.NET>
  6. Date: 3 Aug 87 21:20:32 GMT
  7. Organization: UUNET Communications Services, Arlington, VA
  8. Lines: 1802
  9. Approved: rs@uunet.UU.NET
  10.  
  11. Submitted-by: Roy D'Souza <dsouza%hplabsc@hplabs.HP.COM>
  12. Posting-number: Volume 10, Issue 87
  13. Archive-name: comobj.lisp/Part13
  14.  
  15. #! /bin/sh
  16. # This is a shell archive.  Remove anything before this line, then unpack
  17. # it by saving it into a file and typing "sh file".  To overwrite existing
  18. # files, type "sh file -c".  You can also feed this as standard input via
  19. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  20. # will see the following message at the end:
  21. #        "End of archive 13 (of 13)."
  22. # Contents:  co-parse.l
  23. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  24. if test -f 'co-parse.l' -a "${1}" != "-c" ; then 
  25.   echo shar: Will not clobber existing file \"'co-parse.l'\"
  26. else
  27. echo shar: Extracting \"'co-parse.l'\" \(56836 characters\)
  28. sed "s/^X//" >'co-parse.l' <<'END_OF_FILE'
  29. X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  30. X;
  31. X; File:         co-parse.l
  32. X; RCS:          $Revision: 1.1 $
  33. X; SCCS:         %A% %G% %U%
  34. X; Description:  Commonobjects parser for the Commonobjects-Commonloops
  35. X;               interface.
  36. X; Author:       Roy D'Souza, HPL/DCC
  37. X; Created:      20-Nov-86
  38. X; Modified:     4-Mar-87 11:22:29 (James Kempf)
  39. X; Mode:         Lisp
  40. X; Package:      COMMON-OBJECTS-PARSER
  41. X; Status:       Distribution
  42. X;
  43. X; (c) Copyright 1987, HP Labs, all rights reserved.
  44. X;
  45. X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  46. X;
  47. X; Copyright (c) 1987 Hewlett-Packard Corporation. All rights reserved.
  48. X;
  49. X; Use and copying of this software and preparation of derivative works based
  50. X; upon this software are permitted.  Any distribution of this software or
  51. X; derivative works must comply with all applicable United States export
  52. X; control laws.
  53. X; 
  54. X; This software is made available AS IS, and Hewlett-Packard Corporation makes
  55. X; no warranty about the software, its performance or its conformity to any
  56. X; specification.
  57. X;
  58. X; Suggestions, comments and requests for improvement may be mailed to
  59. X; aiws@hplabs.HP.COM
  60. X
  61. X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  62. X; Preliminaries
  63. X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  64. X
  65. X(provide "co-parse")
  66. X
  67. X;;;Package COMMON-OBJECTS-PARSER contains the parser. For ease of
  68. X;;;  typing, CO-PARSER can be used.
  69. X
  70. X;;;These symbols from the COMMON-OBJECTS package are needed at compile
  71. X;;;  time. Create the package if not there. Note that I don't want
  72. X;;;  to export them, because a user of the COMMON-OBJECTS package
  73. X;;;  shouldn't know about them. I therefore use fully qualified
  74. X;;;  symbols in the code.
  75. X
  76. X(in-package :common-objects :nicknames '(co) :use '(lisp pcl))
  77. X(intern "ASSIGNEDP")
  78. X(intern "METHOD-ALIST")
  79. X(intern "SELF")
  80. X(intern "INIT-KEYWORDS")
  81. X(intern "LEGAL-PARENT-P")
  82. X(in-package 'common-objects-parser :nicknames '(co-parser) :use '(lisp pcl))
  83. X
  84. X;;Export functions needed for parsing
  85. X
  86. X(export
  87. X  '(
  88. X    co-parse-define-type-call
  89. X    co-parse-method-macro-call
  90. X    co-parse-call-to-method
  91. X    co-process-var-options
  92. X    co-parse-options
  93. X    co-deftype-error
  94. X    co-legal-type-or-method-name
  95. X    $UNDEFINED-TYPE-NAME
  96. X    $TYPE-INFO-SLOT
  97. X    $TYPE-NAME-SLOT
  98. X    $VARIABLE-NAMES-SLOT
  99. X    $INITABLE-VARIABLES-SLOT
  100. X    $SETTABLE-VARIABLES-SLOT
  101. X    $GETTABLE-VARIABLES-SLOT
  102. X    $PARENT-TYPES-SLOT
  103. X    $PARENTS-INFO-SLOT
  104. X    $A-LIST-METHOD-TABLE-SLOT
  105. X    $TREAT-AS-VARIABLES-SLOT
  106. X    $INIT-KEYWORDS-SLOT
  107. X    $NO-INIT-KEYWORD-CHECK-SLOT
  108. X    $METHODS-TO-NOT-DEFINE-SLOT
  109. X    $METHODS-TO-INHERIT-SLOT
  110. X    $LET-PSEUDO-INFO-SLOT
  111. X    $INFO-NUMBER-OF-SLOTS
  112. X
  113. X  )
  114. X)
  115. X
  116. X;;Need the PCL and pcl-patches module
  117. X(require "pcl")
  118. X(require "pcl-patches")
  119. X
  120. X
  121. X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  122. X; Constant Definition
  123. X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  124. X
  125. X;;Type names are set to this when types are undefined.
  126. X
  127. X(defconstant $UNDEFINED-TYPE-NAME '*now-an-undefined-type*)
  128. X
  129. X;;Offsets into the vector used to parse type definitions.
  130. X
  131. X(defconstant $TYPE-INFO-SLOT 0)
  132. X
  133. X(defconstant $TYPE-NAME-SLOT 1)
  134. X
  135. X(defconstant $VARIABLE-NAMES-SLOT 2)
  136. X
  137. X(defconstant $INITABLE-VARIABLES-SLOT 3)
  138. X
  139. X(defconstant $SETTABLE-VARIABLES-SLOT 4)
  140. X
  141. X(defconstant $GETTABLE-VARIABLES-SLOT 5)
  142. X
  143. X(defconstant $PARENT-TYPES-SLOT 6)
  144. X
  145. X(defconstant $PARENTS-INFO-SLOT 7)
  146. X      
  147. X(defconstant $A-LIST-METHOD-TABLE-SLOT 8)
  148. X
  149. X(defconstant $TREAT-AS-VARIABLES-SLOT 9)
  150. X
  151. X(defconstant $INIT-KEYWORDS-SLOT 10)
  152. X
  153. X(defconstant $NO-INIT-KEYWORD-CHECK-SLOT 11)
  154. X
  155. X(defconstant $METHODS-TO-NOT-DEFINE-SLOT 12)
  156. X
  157. X(defconstant $METHODS-TO-INHERIT-SLOT 13)
  158. X
  159. X(defconstant $LET-PSEUDO-INFO-SLOT 14)
  160. X      
  161. X(defconstant $EXPLICITLY-LISTED-METHODS-SLOT 15)
  162. X
  163. X;;List of all universal method names
  164. X
  165. X(defconstant
  166. X $DEFINE-TYPE-UNIVERSAL-METHODS
  167. X '(:describe
  168. X   :print
  169. X   :initialize
  170. X   :initialize-variables
  171. X   :init
  172. X   :eql
  173. X   :equal
  174. X   :equalp
  175. X   :typep
  176. X   :copy
  177. X   :copy-state
  178. X   :copy-instance)
  179. X)
  180. X
  181. X;;Size of the vector used in type definition parsing.
  182. X
  183. X(defconstant $INFO-NUMBER-OF-SLOTS 16)
  184. X
  185. X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  186. X; General Macro Definitions
  187. X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  188. X
  189. X(defmacro get-parents-info (type-info)
  190. X
  191. X; Allow for more convenient access of parent information.
  192. X
  193. X `(aref ,type-info $parents-info-slot))
  194. X
  195. X(defmacro set-parents-info (type-info new-value)
  196. X `(setf (aref ,type-info $parents-info-slot) ,new-value))
  197. X
  198. X(defmacro co-deftype-error (format &rest arguments)
  199. X
  200. X  `(error (concatenate 'simple-string
  201. X               "DEFINE-TYPE: In type '~s', "
  202. X               ,format)
  203. X        ,@arguments))
  204. X
  205. X
  206. X(defmacro define-method-error (format &rest arguments)
  207. X
  208. X `(error
  209. X    (format nil
  210. X            (concatenate 'simple-string "DEFINE-METHOD: " ,format)
  211. X            ,@arguments)))
  212. X
  213. X(defmacro return-keyword-from-variable (var)
  214. X    `(intern ,var (find-package "KEYWORD"))
  215. X)
  216. X
  217. X;;type-partially-defined?-Find out if a CommonLoops class is
  218. X;;  defined and return the class object if so. 
  219. X
  220. X(defmacro type-partially-defined? (name)
  221. X
  222. X `(class-named ,name T))
  223. X
  224. X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  225. X; General Function and Method Definitions
  226. X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  227. X
  228. X;;type-name-Return the name of the type
  229. X
  230. X(defun type-name (tinfo) 
  231. X
  232. X   (if (%instancep tinfo)
  233. X     (class-name tinfo)
  234. X     (svref tinfo $TYPE-NAME-SLOT)
  235. X   )
  236. X
  237. X) ;type-name
  238. X
  239. X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  240. X; Top Level Type Definition
  241. X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  242. X
  243. X
  244. X(defun co-parse-define-type-call
  245. X (define-type-call type-name doc-string options-list)
  246. X
  247. X; Parse the various pieces of the call to DEFINE-TYPE.  Return multiple values
  248. X; of the form: (TYPE-NAME DOC-STRING OPTIONS-LIST) OPTIONS-LIST doesn't have to
  249. X; exist.  If it doesn't, NIL is returned for it value (assuming NIL is
  250. X; given as their initial value passed into the routine).  In either
  251. X; case it is disreguarded.  Example call, DEFINE-TYPE-CALL =
  252. X; (DEFINE-TYPE NOSE (:INHERIT-FROM PARENT)).
  253. X
  254. X (setf define-type-call (cdr define-type-call))
  255. X
  256. X; This should now be the list of arguments to the DEFINE-TYPE.
  257. X; Example define-type-call = (NOSE (:INHERIT-FROM PARENT)).
  258. X
  259. X (unless (proper-list define-type-call)
  260. X
  261. X ; THEN The call to DEFINE-TYPE is not a proper list.
  262. X
  263. X   (error
  264. X    (format nil
  265. X            "DEFINE-TYPE: The call,~% (DEFINE-TYPE '~S'),~% is missing arguments or is not a proper list."
  266. X            define-type-call)))
  267. X
  268. X; Get the name of the type
  269. X
  270. X (setf type-name (first define-type-call))
  271. X (setf define-type-call (cdr define-type-call))
  272. X
  273. X; see if there is a documentation string
  274. X
  275. X (when
  276. X   (setq doc-string
  277. X          (and (consp define-type-call)
  278. X               (stringp (car (the cons define-type-call)))
  279. X               (list (car (the cons define-type-call)))
  280. X          ; list form for ,@ substitution
  281. X          ))
  282. X   (setf define-type-call (cdr define-type-call)))
  283. X
  284. X; Example, define-type-call = ((:INHERIT-FROM PARENT)).
  285. X; Now look for options.
  286. X
  287. X (when (consp define-type-call)
  288. X
  289. X ; THEN We have options.
  290. X
  291. X   (setf options-list define-type-call))
  292. X
  293. X; Return the parsed fields as a list for MULTIPLE-VALUE-SETQ
  294. X
  295. X (values type-name doc-string options-list)
  296. X
  297. X) ;co-parse-define-type-call
  298. X
  299. X;;proper-list-Return T if X is a proper list, i.e., no dotted tail
  300. X
  301. X(defun proper-list (x)
  302. X
  303. X; Return T on if x is a proper list (i.e., not (a b c . d)).  NIL is
  304. X; not considered a proper list.
  305. X
  306. X (and (consp x) (not (cdr (last x)))))
  307. X
  308. X(defun co-process-var-options
  309. X (type-info options-list var-names var-assignments)
  310. X
  311. X; Returns multiple values.  These values are:
  312. X;    (VAR-NAMES VAR-ASSIGNMENTS OPTIONS-LIST)
  313. X; Go through OPTIONS-LIST and find all the :VAR options.  Take
  314. X; these and process them producing the list of variable names, the
  315. X; variable assignment code and the list of options without the :VAR
  316. X; options.
  317. X
  318. X  (let
  319. X   (
  320. X     (variable nil)
  321. X     (var-assignment nil)
  322. X     (new-options-list nil)
  323. X     (option-name nil)
  324. X     (option-info nil)
  325. X   )
  326. X;;;;    (Declare (ignore option-name))
  327. X
  328. X   (dolist (option options-list 
  329. X            (values var-names var-assignments new-options-list)
  330. X           )
  331. X
  332. X   (multiple-value-setq (option-name  option-info)
  333. X            (option-ok? option type-info 'regular-option)
  334. X   )
  335. X
  336. X   ; Will only return to here if we didn't get an error.
  337. X
  338. X   ; Check if spec is an instance variable spec
  339. X
  340. X   (if (not (member 'variable-option (cdr option-info) :test #'eq))
  341. X
  342. X    ;;THEN Add this non-:VAR option to the options list
  343. X
  344. X    (setf new-options-list (nconc new-options-list (list option)))
  345. X
  346. X
  347. X
  348. X   ; ELSE We have a instance variable specification.
  349. X   ;      Now return the name of the variable and initialization
  350. X   ;      code.
  351. X
  352. X   
  353. X    (progn
  354. X      (multiple-value-setq (variable var-assignment)
  355. X                   (parse-option
  356. X                 type-info
  357. X                 var-names
  358. X                 option
  359. X                 option-info
  360. X                           )
  361. X      )
  362. X
  363. X      (setf var-names (nconc var-names (list variable)))
  364. X
  365. X      (when var-assignment
  366. X
  367. X        ; THEN Add the assignment to the list of assignments.
  368. X
  369. X        (setf var-assignments
  370. X           (nconc var-assignments (list var-assignment))
  371. X        )
  372. X      ) ;when
  373. X
  374. X    ) ;progn
  375. X
  376. X  ) ;if
  377. X ); dolist
  378. X
  379. X ) ;let
  380. X
  381. X); end co-process-var-options
  382. X
  383. X(defun co-parse-options (type-info var-names options)
  384. X
  385. X; It is legal for OPTIONS to be NIL.
  386. X; Example: OPTIONS = ((:REDEFINED-METHODS m1 m2 m3)
  387. X;                     :ALL-INITABLE)
  388. X
  389. X (let ((options-so-far nil)
  390. X       (option-name nil)
  391. X       (option-info nil))
  392. X
  393. X   (dolist (option options)
  394. X
  395. X   ; OPTION-INFO will be NIL if OPTION-NAME is not a legal
  396. X   ; option, or a list of information that tells what
  397. X   ; characteristics this option has.  Note that currently, if an
  398. X   ; error occurs in OPTION-OK? we will NOT return to this
  399. X   ; function.  The check for '(WHEN OPTION-INFO...' is for future
  400. X   ; continuable errors. If 'ONCE' is on this list, it means the
  401. X   ; option can only occur once.
  402. X
  403. X           (multiple-value-setq (option-name  option-info)
  404. X                          (option-ok? option type-info 'regular-option))
  405. X           (when option-info
  406. X
  407. X           ; THEN The OPTION is a real one.
  408. X           ;      Now make sure it doesn't occur more then once.
  409. X
  410. X             (if
  411. X               (and (member option-name options-so-far :test #'eq)
  412. X
  413. X                    (member 'once (cdr option-info) :test #'eq))
  414. X
  415. X             ; THEN We have duplicate options.  Give an error.
  416. X
  417. X               (co-deftype-error
  418. X                "duplicate option,~% '~s',~% specified."
  419. X                (type-name type-info)
  420. X                option)
  421. X
  422. X             ; ELSE Everything is ok.
  423. X
  424. X               (progn
  425. X                 (setf options-so-far (cons option-name options-so-far))
  426. X                 (parse-option type-info var-names option option-info)))))
  427. X ))
  428. X
  429. X(defun parse-option (type-info var-names option option-info)
  430. X
  431. X; This routine calls the right function to parse OPTION.  This
  432. X; function is the first element of OPTION-INFO.  Example: OPTION =
  433. X; (:REDEFINED-METHODS M1 M2 M3) The option given is either a symbol
  434. X; or a list.  When a list, the rest of the arguments will be passed to
  435. X; the function (may be NIL).  If a symbol, NIL is passed as arguments.
  436. X; NOTE: Should make sure that the value returned by the option is
  437. X;       the value of this routine, since some code may want to use
  438. X;       the value returned (like the caller of the :VAR option).
  439. X
  440. X (apply (car option-info)
  441. X        (list var-names (if (consp option) (cdr option) nil) type-info)))
  442. X
  443. X(defun option-ok? (option type-info type-of-option)
  444. X
  445. X; Return the information about this option or NIL.  Return the name of
  446. X; the option followed by the information for the option as a pair.  If
  447. X; the option is not of the correct form give an error message.  Check
  448. X; to make sure the option exists.  Also check that the form of option
  449. X; is legal according to the information returned.  This includes
  450. X; whether the option is allowed as a symbol or in list form.  And
  451. X; whether it is allowed to not have any arguments when in the list
  452. X; form.  Also if a list, check if each element is a symbol, and not NIL.
  453. X; This is done if CHECK-ARGUMENTS was included in the option
  454. X; information.  If the KEYWORDS option is also included with
  455. X; CHECK-ARGUMENTS, each of the symbols given must also be in the
  456. X; keyword package.  If VARIABLES is included in the option information,
  457. X; SELF is also checked for each option element.  The
  458. X; option CAN-HAVE-LIST-ELEMENTS causes list element arguments to be
  459. X; ignored. If this option is not there and a list element is
  460. X; found, an error message is issued.  Type-info is used strictly for
  461. X; error messages.  Will return NIL for the error conditions.  Sample,
  462. X;
  463. X; OPTION = '(:REDEFINED-METHODS A B C)' or ':ALL-SETTABLE'
  464. X;
  465. X; TYPE-OF-OPTION is used to decide wheter we are dealing with an
  466. X; option or a suboption of :INHERIT-FROM.  NOTE: Currently, this
  467. X; function will never return if an error occurs but we prepare for
  468. X; future continuable errors.  
  469. X
  470. X (let*
  471. X   ((option-info
  472. X     (if (consp option)
  473. X
  474. X     ; THEN Use the first element of the option as the option name.
  475. X
  476. X       (return-option-info (car option) type-of-option)
  477. X
  478. X     ; ELSE Use the option itself as the option name.
  479. X
  480. X       (return-option-info option type-of-option)))
  481. X
  482. X    (type-name (type-name type-info))
  483. X    (check-as-variables (member 'variable option-info :test #'eq))
  484. X    (can-have-list-elements
  485. X     (member 'can-have-list-elements option-info :test #'eq))
  486. X    (keyword-arguments (member 'keywords option-info :test #'eq)))
  487. X
  488. X
  489. X   (unless option-info
  490. X
  491. X   ; THEN We have an illegal option.
  492. X
  493. X     (co-deftype-error
  494. X      "no such option (or suboption) as:~% '~s'."
  495. X      type-name
  496. X      option))
  497. X
  498. X ; We have a real option.  Make sure it is of the right form.
  499. X
  500. X   (if (consp option)
  501. X
  502. X   ; THEN Check to make sure it can be a pair.
  503. X
  504. X     (if
  505. X       (not (member 'list (cdr option-info) :test #'eq))
  506. X
  507. X     ; THEN Wrong form for option.
  508. X
  509. X       (co-deftype-error
  510. X        "option,~% '~S',~% must occur as a symbol."
  511. X        type-name
  512. X        option)
  513. X
  514. X     ; ELSE Ok so far.  Make sure the list form is a proper list.
  515. X     ; Now check if the option has no arguments and if
  516. X     ; if does make sure it can.
  517. X
  518. X       (progn
  519. X         (unless (proper-list option)
  520. X         ; THEN Not a proper list.
  521. X           (co-deftype-error
  522. X            "the option,~% '~S',~% must be a proper list."
  523. X            type-name
  524. X            option))
  525. X         (if
  526. X           (and (not (cdr option))
  527. X                (not (member 'no-arguments (cdr option-info) :test #'eq)))
  528. X         
  529. X         ; THEN Arguments must be specified to option.
  530. X         
  531. X           (co-deftype-error
  532. X            "option,~% '~S',~% requires arguments."
  533. X            type-name
  534. X            option)
  535. X
  536. X         ; ELSE Check each element of the list, if necessary, to
  537. X         ; make sure it is a symbol, not NIL. Also check for 
  538. X         ; SELF if VARIABES is in the
  539. X         ; option info.
  540. X         ; Return the information.
  541. X
  542. X           (progn
  543. X             (when (member 'check-arguments (cdr option-info) :test #'eq)
  544. X
  545. X             ; THEN Check the arguments.
  546. X
  547. X               (dolist (option-arg (cdr option))
  548. X                       (if (consp option-arg)
  549. X                         (unless can-have-list-elements
  550. X
  551. X                         ; THEN List arguments are not allowed.
  552. X
  553. X                           (co-deftype-error
  554. X                            "illegal argument '~S' found in option,~% '~S'."
  555. X                            type-name
  556. X                            option-arg
  557. X                            option))
  558. X
  559. X                       ; ELSE Check if a correct symbol.
  560. X
  561. X                         (if
  562. X                           (or
  563. X                             (not (co-legal-type-or-method-name option-arg))
  564. X                             (and check-as-variables
  565. X                                  (not
  566. X                                    (legal-instance-variable))))
  567. X
  568. X                         ; THEN Illegal argument in option.
  569. X
  570. X                           (co-deftype-error
  571. X                            "illegal argument '~S' found in option,~% '~S'."
  572. X                            type-name
  573. X                            option-arg
  574. X                            option)
  575. X
  576. X                         ; ELSE Check if the option-arg must be a keyword.
  577. X
  578. X                           (when
  579. X                             (and keyword-arguments
  580. X                                  (not (keywordp option-arg)))
  581. X
  582. X                           ; THEN We have a DEFINE-TYPE in which the
  583. X                           ;      arguments must all be symbols in the
  584. X                           ;      keyword package.
  585. X                             (co-deftype-error
  586. X                              "'~S' of the option,~%'~S'~%is illegal.  Must be a symbol from the keyword package."
  587. X                              type-name
  588. X                              option-arg
  589. X                              option))))))
  590. X             (values (car option) option-info)))))
  591. X
  592. X   ; ELSE We have the symbol form of the option.
  593. X
  594. X     (if (member 'symbol (cdr option-info) :test #'eq)
  595. X
  596. X     ; THEN Return the information.
  597. X
  598. X       (values option option-info)
  599. X
  600. X     ; ELSE Wrong form for option.
  601. X
  602. X       (co-deftype-error
  603. X        "option,~% '~S',~% must occur in list form."
  604. X        type-name
  605. X        option)))))
  606. X
  607. X
  608. X(defun co-legal-type-or-method-name (type-or-method-name)
  609. X
  610. X; Return T only if the name given is a non-nil symbol.
  611. X
  612. X (and (symbolp type-or-method-name) type-or-method-name))
  613. X
  614. X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  615. X; Detailed Option Parsing
  616. X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  617. X
  618. X(defun return-option-info (option-name option-type)
  619. X
  620. X; Whenever a new option is added, this function must be updated.
  621. X; Should return NIL, if garbage option-names are given.  The option
  622. X; information returned has the form:
  623. X;     (FUNCTION-NAME . INFORMATION).
  624. X; FUNCTION-NAME is the name of the function to call that parses the
  625. X; given option.  INFORMATION is a list of information to use in
  626. X; syntaxing the option.  This list includes:
  627. X;    SYMBOL          - option can occur in symbol form.
  628. X;    LIST            - option can occur in list form.
  629. X;    CHECK-ARGUMENTS - When an option is in list form, this specifies that
  630. X;                      each element of the option list is to be checked to 
  631. X;                      be a symbol which is not NIL.
  632. X;    KEYWORDS        - An addition to the CHECK-ARGUMENTS option, this says
  633. X;                      that each element must be a symbol from the keyword 
  634. X;                      package.  Must occur with the CHECK-ARGUMENTS option.
  635. X;    NO-ARGUMENTS    - This specifies that a list form of the option can 
  636. X;                      occur without any arguments (i.e.,
  637. X;                      (:METHODS).
  638. X;    VARIABLE        - The items in this options list are instance variables.
  639. X;                      Check that they are not SELF or MYSELF.Make sure 
  640. X;               they are not symbols from the
  641. X;                      keyword package.
  642. X;    CAN-HAVE-LIST-ELEMENTS - This option says that having list elements is 
  643. X;                             legal. These elements are simply ignored.
  644. X;    ONCE            - This option can only occur once.
  645. X;    VARIABLE-OPTION - Currently used in the :VAR option.  Tells whether
  646. X;                      an option is a variable option (:VAR) without
  647. X;                      using the name of the option.  This allows easy
  648. X;                      renaming of the :VAR option.
  649. X;    VALUE-RETURNED-SUBOPTION - States that this suboption returns a
  650. X;                               value that is needed.  A test is made
  651. X;                               to save the return value when a suboption
  652. X;                               has this characteristic.
  653. X;    
  654. X; Note that this list is used for parsing suboptions as well as
  655. X; options.  The handling of suboptions and options in the same way is
  656. X; done for flexibility and understandability even though some of the
  657. X; options may not currently apply to both options and suboptions.
  658. X;
  659. X
  660. X (case option-type
  661. X
  662. X   (var-suboption (return-var-suboption-info option-name))
  663. X
  664. X   (inherit-from-suboption
  665. X    (return-inherit-from-suboption-info option-name))
  666. X
  667. X   (regular-option (return-regular-option-info option-name))))
  668. X
  669. X(defun return-var-suboption-info (option-name)
  670. X
  671. X; Return information as stated in comments of RETURN-OPTION-INFO
  672. X; about the suboptions of the :VAR option.
  673. X
  674. X (case option-name
  675. X
  676. X   (:init '(parse-var-init-suboption list once value-returned-suboption))
  677. X
  678. X   (:type '(parse-var-type-suboption list once))
  679. X
  680. X   (:initable '(parse-var-initable-suboption symbol once))
  681. X
  682. X   (:settable '(parse-var-settable-suboption symbol once))
  683. X
  684. X   (:gettable '(parse-var-gettable-suboption symbol once))
  685. X
  686. X   (otherwise nil)
  687. X ))
  688. X
  689. X(defun parse-var-initable-suboption (args initable-variable type-info)
  690. X  (declare (ignore args))
  691. X
  692. X; ARGS will always be NIL.
  693. X
  694. X (setf (svref type-info $initable-variables-slot)
  695. X        (add-to-set
  696. X         (svref type-info $initable-variables-slot)
  697. X         initable-variable)))
  698. X
  699. X(defun parse-var-gettable-suboption (args gettable-variable type-info)
  700. X  (declare (ignore args))
  701. X
  702. X; ARGS will always be NIL.
  703. X
  704. X (setf (svref type-info $gettable-variables-slot)
  705. X        (add-to-set
  706. X         (svref type-info $gettable-variables-slot)
  707. X         gettable-variable)))
  708. X
  709. X(defun parse-var-settable-suboption (args settable-variable type-info)
  710. X  (declare (ignore args))
  711. X
  712. X; ARGS will always be NIL.
  713. X
  714. X (setf (svref type-info $initable-variables-slot)
  715. X        (add-to-set
  716. X         (svref type-info $initable-variables-slot)
  717. X         settable-variable))
  718. X
  719. X (setf (svref type-info $gettable-variables-slot)
  720. X        (add-to-set
  721. X         (svref type-info $gettable-variables-slot)
  722. X         settable-variable))
  723. X
  724. X (setf (svref type-info $settable-variables-slot)
  725. X        (add-to-set
  726. X         (svref type-info $settable-variables-slot)
  727. X         settable-variable)))
  728. X
  729. X(defun add-to-set (set new-elements)
  730. X
  731. X; Add the elements in NEW-ELEMENTS to SET if they are not already
  732. X; there.  NEW-ELEMENTS can be a list of id's or an id.  It is assumed
  733. X; that the order of the elements within the set is NOT important.  If
  734. X; NEW-ELEMENTS is NIL, simply return set.
  735. X
  736. X (cond ((null new-elements) set)
  737. X       ((symbolp new-elements)
  738. X
  739. X       ; THEN Add the element to the set, if necessary.
  740. X
  741. X        (adjoin new-elements set :test #'eq))
  742. X
  743. X       (t 
  744. X
  745. X       ; ELSE Add each element of the list of elements.
  746. X
  747. X          (let ((new-set set))
  748. X            (dolist (element new-elements)
  749. X                    (setf new-set (adjoin element new-set :test #'eq)))
  750. X            new-set))))
  751. X
  752. X
  753. X(defun parse-var-type-suboption (args variable type-info)
  754. X
  755. X; Example, ARGS = (FIXNUM).  A declaration like (:TYPE FIXNUM) =>
  756. X; (DECLARE (TYPE FIXNUM A)).
  757. X
  758. X (unless (and (consp args) (= (length args) 1))  ;rds 3/8 eq->=
  759. X
  760. X ; THEN We have something like (:TYPE . 2).
  761. X
  762. X   (co-deftype-error
  763. X    "'~S'~% is an illegal form of :TYPE suboption."
  764. X    (type-name type-info)
  765. X    (cons :type args)))
  766. X
  767. X; Add this declaration to the list of declarations.
  768. X; Note that more will be added to this slot when :VARIABLES suboptions are
  769. X; parsed, and at the end parsing the type. :VARIABLES is, however,
  770. X; currently unsupported.
  771. X
  772. X (setf (svref type-info $let-pseudo-info-slot)
  773. X        (nconc (svref type-info $let-pseudo-info-slot)
  774. X               (list `(declare (type ,(car args) ,variable))))))
  775. X
  776. X
  777. X(defun parse-var-init-suboption (args variable type-info)
  778. X
  779. X; Return the variable initialization form. For example, if VARIABLE = 
  780. X; REAL-PART and ARGS = (0.0), would return:
  781. X;      (unless
  782. X;             (assignedp real-part)
  783. X;             (setf real-part 0.0))         
  784. X
  785. X (unless (and (consp args) (= (length args) 1)) ;rds 3/8 eq->= 
  786. X
  787. X ; THEN We have something like (:INIT 1 2).
  788. X
  789. X   (co-deftype-error
  790. X    "illegal initialization form,~%'~S',~%given for instance variable '~S'."
  791. X    (type-name type-info)
  792. X    (cons :init args)
  793. X    variable))
  794. X
  795. X (let ((default-value (first args)))
  796. X   `(unless 
  797. X       (co::assignedp ,variable)
  798. X
  799. X    ; THEN
  800. X
  801. X      (setf ,variable ,default-value))))
  802. X
  803. X(defun return-inherit-from-suboption-info (option-name)
  804. X
  805. X; Return information as stated in comments of RETURN-OPTION-INFO
  806. X; about the suboptions of the :INHERIT-FROM option.
  807. X
  808. X (case option-name
  809. X
  810. X   (:init-keywords
  811. X    '(parse-init-keywords-suboption
  812. X      symbol
  813. X      list
  814. X      once
  815. X      check-arguments
  816. X      keywords))
  817. X
  818. X   ;;:VARIABLES suboption not allowed in COOL. This is due to
  819. X   ;;  lack of code walker hooks.
  820. X
  821. X#|
  822. X   (:variables
  823. X    '(parse-variables-suboption
  824. X      list
  825. X      once
  826. X      no-arguments
  827. X      check-arguments
  828. X      variable
  829. X      can-have-list-elements))
  830. X|#
  831. X
  832. X   (:methods
  833. X    '(parse-methods-suboption list once check-arguments no-arguments))
  834. X
  835. X   (otherwise nil)))
  836. X
  837. X(defun return-regular-option-info (option-name)
  838. X
  839. X; Return information as stated in comments of RETURN-OPTION-INFO
  840. X; about the options of DEFINE-TYPE.
  841. X
  842. X (case option-name
  843. X
  844. X
  845. X   ;;:FAST-METHODS not supported in COOL. Implementation dependent.
  846. X
  847. X#|
  848. X   (:fast-methods
  849. X    '(parse-fast-methods-option list once check-arguments no-arguments))
  850. X|#
  851. X
  852. X   ;;In line methods are not supported in COOL. Implementation dependent.
  853. X
  854. X#|
  855. X   (:inline-methods
  856. X    '(parse-inline-methods-option list once check-arguments no-arguments))
  857. X
  858. X   (:notinline-methods
  859. X    '(parse-notinline-methods-option
  860. X      list
  861. X      once
  862. X      check-arguments
  863. X      no-arguments))
  864. X
  865. X|#
  866. X
  867. X   (:init-keywords
  868. X    '(parse-init-keywords-option
  869. X      list
  870. X      once
  871. X      check-arguments
  872. X      no-arguments
  873. X      keywords))
  874. X
  875. X   (:no-init-keyword-check
  876. X    '(parse-no-init-keyword-check-option symbol once))
  877. X
  878. X   (:inherit-from '(parse-inherit-from-option list))
  879. X
  880. X   (:var '(parse-var-option list variable-option))
  881. X
  882. X   (:redefined-methods
  883. X    '(parse-redefined-methods-option
  884. X      list
  885. X      once
  886. X      check-arguments
  887. X      no-arguments))
  888. X
  889. X   (:all-settable '(parse-all-settable-option symbol once))
  890. X
  891. X   (:all-gettable '(parse-all-gettable-option symbol once))
  892. X
  893. X   (:all-initable '(parse-all-initable-option symbol once))
  894. X
  895. X   (otherwise nil)))
  896. X
  897. X(defun parse-init-keywords-suboption (type-info parent-type-info args)
  898. X
  899. X; If ARGS is NIL, we have the symbol form.  If ARGS is a list, we have
  900. X; the list form.  Examples: ARGS = NIL
  901. X;                           ARGS = (:EXCEPT j k l), (:EXCEPT)
  902. X; (:INIT-KEYWORDS :EXCEPT) is treated as all keywords.  If this
  903. X; function returns, then everything went ok as far as errors.  If ARGS
  904. X; is a list, we know it is proper, and each init keyword is a symbol and
  905. X; not NIL.  This function may change the $INIT-KEYWORDS-SLOT of
  906. X; type-info.
  907. X
  908. X (let*
  909. X   ((parent-init-keywords
  910. X     (co::init-keywords parent-type-info))
  911. X    (keywords-to-add parent-init-keywords))
  912. X
  913. X   (when args
  914. X
  915. X   ; THEN We have the except form.
  916. X   ;      Check and make sure the :EXCEPT is found.
  917. X
  918. X     (if
  919. X       (not (eq (car args) ':except))
  920. X
  921. X     ; THEN We have an error.
  922. X
  923. X       (co-deftype-error
  924. X        "~%'~S'~% was found following the :INIT-KEYWORDS suboption, expected to see 'EXCEPT'."
  925. X        (type-name type-info)
  926. X        (car args))
  927. X
  928. X     ; ELSE ok so far.
  929. X
  930. X       (progn (setq args (cdr args))
  931. X              (when (consp args)
  932. X
  933. X              ; THEN There is something following the :EXCEPT.
  934. X
  935. X                (dolist (keyword args)
  936. X
  937. X                ; See if the keyword is in the list of REAL 
  938. X                ; keywords for the parent.
  939. X
  940. X                        (if
  941. X                          (not
  942. X                            (member keyword
  943. X                                    parent-init-keywords
  944. X                                    :test
  945. X                                    #'eq))
  946. X
  947. X                        ; THEN Print a warning message is ignore.
  948. X
  949. X                          (warn
  950. X                            (format
  951. X                              NIL
  952. X                              "DEFINE-TYPE: Init keyword, '~A', is not a keyword of '~A' in :INIT-KEYWORDS suboption."
  953. X                              keyword
  954. X                              (type-name parent-type-info)))
  955. X
  956. X                        ; ELSE The keyword is legit.
  957. X
  958. X                          (setf keywords-to-add
  959. X                                 (remove keyword
  960. X                                         keywords-to-add
  961. X                                         :test
  962. X                                         #'eq
  963. X                                         :count
  964. X                                         1))))))))
  965. X
  966. X ; keywords-to-add should be correctly setup now.
  967. X ; Add the elements of this list that are not already there, to the
  968. X ; existing list of keywords for this type.
  969. X
  970. X   (setf (svref type-info $INIT-KEYWORDS-SLOT)
  971. X          (add-to-set
  972. X           (svref type-info $INIT-KEYWORDS-SLOT)
  973. X           keywords-to-add))))
  974. X
  975. X(defun parse-methods-suboption (type-info parent-type-info args)
  976. X
  977. X; At this point, we know that ARGS is a proper list where each element
  978. X; is a symbol that is not NIL.  Sample, args = (:EXCEPT M1 M2 M3),
  979. X; (:EXCEPT), ().  If method names are duplicated, the duplicates are
  980. X; ignored.  This function should change the $METHODS-TO-INHERIT-SLOT as
  981. X; in the following example:
  982. X;    PARENT-TYPE-INFO for PARENT2 and the total methods for PARENT2
  983. X;    are M1, M2,...,M6 and if ARGS = (:EXCEPT M1 M2 M3), and if
  984. X; $METHODS-TO-INHERIT-SLOT looked like:
  985. X;       ((<parent1 type info object> .(M1 M2 M3))), then
  986. X; $METHODS-TO-INHERIT-SLOT would look like:
  987. X;     ((<parent1 type info object> .  (M1 M2 M3))
  988. X;      (<parent2 type info object> . (M4 M5 M6)))
  989. X; after this routine completes.  When this routine finishes, we are
  990. X; guaranteed that each method added to the $METHODS-TO-INHERIT-SLOT is an
  991. X; existing methods of the parent.
  992. X
  993. X (let
  994. X   ((parent-methods
  995. X     (co::method-alist parent-type-info))
  996. X    (methods-to-inherit nil)
  997. X    (except-form?
  998. X     (when (and args (eq (car args) ':except))
  999. X
  1000. X     ; THEN Skip over the :EXCEPT argument.
  1001. X
  1002. X       (setf args (cdr args))
  1003. X       t)))
  1004. X
  1005. X ; ARGS will be NIL or a list at this point.  If NIL, we have (:METHODS)
  1006. X ; or (:METHODS :EXCEPT).
  1007. X
  1008. X   (dolist (method args)
  1009. X           (unless (assoc method parent-methods :test #'eq)
  1010. X
  1011. X           ; THEN The method doesn't exits, give a warning.
  1012. X
  1013. X             (warn
  1014. X               (format nil
  1015. X                       "DEFINE-TYPE: Method '~S' of the :METHODS suboption doesn't~% exist in parent '~S'."
  1016. X                       method
  1017. X                       (type-name parent-type-info)))))
  1018. X   (if except-form?
  1019. X
  1020. X   ; THEN We have the :EXCEPT form. List all methods that are not
  1021. X   ;      specified and are not universal methods.  If 
  1022. X   ;      (:METHODS :EXCEPT), all methods not universal methods are
  1023. X   ;      added.
  1024. X
  1025. X     (dolist (method-function-pair parent-methods)
  1026. X
  1027. X     ; As long as the method is not an exception (:EXCEPT)
  1028. X     ; and not a universal method of the parent, inherit it.
  1029. X
  1030. X             (unless
  1031. X               (or (member (car method-function-pair) args :test #'eq)
  1032. X                   (member (car method-function-pair)
  1033. X               $DEFINE-TYPE-UNIVERSAL-METHODS
  1034. X                           :test
  1035. X                           #'eq))
  1036. X
  1037. X             ; THEN The method we are looking at is desired 
  1038. X             ;      for inheritance.
  1039. X
  1040. X               (setf methods-to-inherit
  1041. X                      (add-to-set
  1042. X                       methods-to-inherit
  1043. X                       (car method-function-pair)))))
  1044. X
  1045. X   ; ELSE We have the normal form.  If some of the args were not real
  1046. X   ;      methods. If (:METHODS), nothing is done.
  1047. X
  1048. X     (dolist (method args)
  1049. X             (when (assoc method parent-methods :test #'eq)
  1050. X
  1051. X             ; THEN The method really exists.
  1052. X
  1053. X               (setf methods-to-inherit
  1054. X                      (add-to-set methods-to-inherit method))
  1055. X
  1056. X             ; Add to the list of explicitly stated methods to inherit.
  1057. X             ; This is used for error checking with methods to not
  1058. X             ; redefine later.
  1059. X
  1060. X               (setf
  1061. X                 (svref type-info $EXPLICITLY-LISTED-METHODS-SLOT)
  1062. X                  (add-to-set
  1063. X                   (svref type-info
  1064. X                          $EXPLICITLY-LISTED-METHODS-SLOT)
  1065. X                   method)))))
  1066. X
  1067. X ; Now add this list of methods to the type-info vector.
  1068. X ; 'methods-to-inherit' may be NIL.
  1069. X
  1070. X   (setf (svref type-info $METHODS-TO-INHERIT-SLOT)
  1071. X          (append (svref type-info $METHODS-TO-INHERIT-SLOT)
  1072. X                  (list (cons parent-type-info methods-to-inherit))))))
  1073. X
  1074. X
  1075. X(defun parse-var-option (var-names args type-info)
  1076. X
  1077. X; ARGS = (IV1 (:TYPE INTEGER) (:INIT 0.0) :SETTABLE) Return something
  1078. X; of the form:
  1079. X;    (VARIABLE-NAME . VAR-ASSIGNMENT)
  1080. X; VARIABLE-NAME is the name of the instance variable.  VAR-ASSIGNMENT
  1081. X; is the code needed to initialize this instance variable.
  1082. X
  1083. X (unless (and (consp args) (symbolp (car args)))
  1084. X
  1085. X ; THEN We have an error.
  1086. X
  1087. X   (co-deftype-error
  1088. X    "a symbol must follow a :VAR option."
  1089. X    (type-name type-info)))
  1090. X
  1091. X (let ((variable (car args))
  1092. X       (var-assignment nil))
  1093. X
  1094. X ; Make sure the instance variable name is legal.
  1095. X
  1096. X   (instance-variable-ok? variable var-names (type-name type-info))
  1097. X
  1098. X ; Now parse all the suboptions of the :VAR option.
  1099. X ; VAR-ASSIGNMENT will be NIL if there is no :INIT suboption.
  1100. X
  1101. X   (setf var-assignment
  1102. X          (parse-var-suboptions type-info (cdr args) variable))
  1103. X   (values variable var-assignment)))
  1104. X
  1105. X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1106. X; Detailed :VAR Suboption Parsing
  1107. X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1108. X
  1109. X(defun parse-var-suboptions (type-info suboptions variable)
  1110. X
  1111. X; This routine returns the code for initialization of the instance
  1112. X; variable VARIABLE.  It is legal for suboptions to be NIL.  For
  1113. X; understandibility, expandability, and consistancy the parsing of
  1114. X; suboptions uses the same techniques with the same keywords that option
  1115. X; option parsing does.  This is true even though some of the option
  1116. X; information may not be shared between options and suboptions.  See
  1117. X; CO-PARSE-OPTIONS and its constituent routines.
  1118. X;
  1119. X; Example: SUBOPTIONS = ((:INIT 0.0)
  1120. X;                        (:TYPE INTEGER)
  1121. X;                        :SETTABLE)
  1122. X
  1123. X (let ((suboptions-so-far nil)
  1124. X       (suboption-name nil)
  1125. X       (suboption-info nil)
  1126. X       (init-info nil)
  1127. X      )
  1128. X
  1129. X   (dolist (suboption suboptions)
  1130. X
  1131. X               ; SUBOPTION-INFO will be NIL if SUBOPTION-NAME is not a
  1132. X               ; legal suboption, or a list of information that tells what
  1133. X               ; characteristics this suboption has.  Note that currently,
  1134. X               ; if an error occurs in SUBOPTION-OK? we will NOT return
  1135. X               ; to this function. The check for '(WHEN SUBOPTION-INFO...)'
  1136. X               ; is for future continuable errors. If 'ONCE' is on this
  1137. X               ; list, it means the suboption can only occur once.
  1138. X
  1139. X                (multiple-value-setq (suboption-name suboption-info)
  1140. X                               (option-ok?
  1141. X                                suboption
  1142. X                                type-info
  1143. X                                'var-suboption))
  1144. X                (when suboption-info
  1145. X
  1146. X                ; THEN The suboption is a real one.
  1147. X                ;      Now make sure it doesn't occur more then once.
  1148. X
  1149. X                  (if
  1150. X                    (and
  1151. X                      (member suboption-name suboptions-so-far :test #'eq)
  1152. X                      (member 'once (cdr suboption-info) :test #'eq))
  1153. X
  1154. X                  ; THEN We have duplicate suboptions.  Give an error.
  1155. X
  1156. X                    (co-deftype-error
  1157. X                     "duplicate suboption,~% '~S',~% specified to :VAR option."
  1158. X                     (type-name type-info)
  1159. X                     suboption)
  1160. X
  1161. X                  ; ELSE Everything is ok.
  1162. X
  1163. X                    (progn
  1164. X                      (setf suboptions-so-far
  1165. X                             (cons suboption-name suboptions-so-far))
  1166. X                      (if
  1167. X                        (member 'value-returned-suboption
  1168. X                                (cdr suboption-info)
  1169. X                                :test
  1170. X                                #'eq)
  1171. X
  1172. X                      ; THEN We must save the return value.
  1173. X
  1174. X                        (setf init-info
  1175. X                               (parse-var-suboption
  1176. X                                type-info
  1177. X                                variable
  1178. X                                suboption
  1179. X                                suboption-info))
  1180. X
  1181. X                      ; ELSE We don't care about the return value.
  1182. X
  1183. X                        (parse-var-suboption
  1184. X                         type-info
  1185. X                         variable
  1186. X                         suboption
  1187. X                         suboption-info)))))
  1188. X
  1189. X      ) ;dolist
  1190. X
  1191. X      ;;Return the init-info
  1192. X
  1193. X      init-info
  1194. X
  1195. X  ) ;let
  1196. X
  1197. X) ;end parse-var-suboptions
  1198. X
  1199. X(defun parse-var-suboption (type-info variable suboption suboption-info)
  1200. X
  1201. X; This routine calls the right function to parse SUBOPTION.  This
  1202. X; function is the first element of SUBOPTION-INFO.  Example:
  1203. X; SUBOPTION = (:INIT 0.0) The SUBOPTION given is either a symbol or a
  1204. X; list.  When a list, the rest of the arguments will be passed to the
  1205. X; function (may be NIL).  If a symbol, NIL is passed as arguments.
  1206. X; NOTE: Should make sure that the value returned by the suboption is
  1207. X;       the value of this routine, since some code may want to use
  1208. X;       the value returned (like the value of the :INIT suboption).
  1209. X
  1210. X (apply (car suboption-info)
  1211. X        (list (if (consp suboption) (cdr suboption) nil)
  1212. X              variable
  1213. X              type-info)))
  1214. X
  1215. X
  1216. X(defun instance-variable-ok? (variable list-of-variables type-name)
  1217. X
  1218. X; Signal a standard error if the variable is SELF,
  1219. X; one of the variables that are already in the list
  1220. X; of variables, or a keyword.
  1221. X; TYPE-NAME is used for error messages by CO-DEFTYPE-ERROR.
  1222. X
  1223. X (unless (legal-instance-variable variable)
  1224. X
  1225. X ; THEN error.
  1226. X
  1227. X     (co-deftype-error
  1228. X      "'SELF' NIL, or symbol from the keyword package~%was found as an instance variable."
  1229. X      type-name))
  1230. X
  1231. X (when (member variable list-of-variables :test #'eq)
  1232. X
  1233. X ; THEN We have a duplicate variable.
  1234. X
  1235. X   (co-deftype-error
  1236. X    "instance variable '~S' occurs more~%than once."
  1237. X    type-name
  1238. X    variable)))
  1239. X
  1240. X(defun legal-instance-variable (variable)
  1241. X
  1242. X; Return T if VARIABLE satisfies restrictions on instance variables.
  1243. X; Return NIL otherwise.  Currently, the variable must be a non-NIL symbol
  1244. X; that is not SELF.
  1245. X; Must also be a symbol that is NOT in the
  1246. X; keyword package.
  1247. X
  1248. X (and (symbolp variable)
  1249. X      variable
  1250. X      (not (eq variable 'co::self))
  1251. X      (not (keywordp variable))))
  1252. X
  1253. X
  1254. X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1255. X; Parsing of :ALL-xxx
  1256. X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1257. X
  1258. X(defun parse-all-initable-option (var-names args type-info)
  1259. X
  1260. X; Parses: :ALL-INITABLE.  ARGS will be NIL.
  1261. X
  1262. X (parse-initable-option var-names args type-info))
  1263. X
  1264. X(defun parse-all-gettable-option (var-names args type-info)
  1265. X
  1266. X; Parses: :ALL-GETTABLE.  ARGS will be NIL.
  1267. X
  1268. X (parse-gettable-option var-names args type-info))
  1269. X
  1270. X(defun parse-all-settable-option (var-names args type-info)
  1271. X
  1272. X; Parses: :ALL-SETTABLE.  ARGS will be NIL.
  1273. X
  1274. X (parse-settable-option var-names args type-info))
  1275. X
  1276. X(defun parse-gettable-option (var-names args type-info)
  1277. X
  1278. X; Example ARGS = (A B C D), NIL.
  1279. X; Duplicate variables specified are ignored.
  1280. X
  1281. X (dolist (gettable-variable (or args var-names))
  1282. X
  1283. X         (if (member gettable-variable var-names :test #'eq)
  1284. X
  1285. X         ; THEN This variable is a real instance variable.
  1286. X
  1287. X           (setf (svref type-info  $gettable-variables-slot)
  1288. X                  (add-to-set
  1289. X                   (svref type-info $GETTABLE-VARIABLES-SLOT)
  1290. X                   gettable-variable))
  1291. X         ; ELSE We have an illegal variable name.
  1292. X
  1293. X           (co-deftype-error
  1294. X            "variable '~S' in the settable~% options list is not an instance variable.~%"
  1295. X            (type-name type-info)
  1296. X            gettable-variable))))
  1297. X
  1298. X(defun parse-settable-option (var-names args type-info)
  1299. X
  1300. X; Example ARGS = (A B C D), NIL.  Duplicate variables specified are
  1301. X; ignored. Each settable instance variable
  1302. X; is added to the list of gettable and initable instance variables as
  1303. X; well.
  1304. X
  1305. X (dolist (settable-variable (or args var-names))
  1306. X
  1307. X         (if (not (member settable-variable var-names :test #'eq))
  1308. X
  1309. X         ; THEN We have an illegal variable name.
  1310. X
  1311. X           (co-deftype-error
  1312. X            "variable '~S' in the settable~% options list is not an instance variable~%."
  1313. X            (type-name type-info)
  1314. X            settable-variable)
  1315. X
  1316. X         ; ELSE This variable is a real instance variable.
  1317. X
  1318. X           (progn
  1319. X             (setf (svref type-info $initable-variables-slot)
  1320. X                    (add-to-set
  1321. X                     (svref type-info $initable-variables-slot)
  1322. X                     settable-variable))
  1323. X             (setf (svref type-info $gettable-variables-slot)
  1324. X                    (add-to-set
  1325. X                     (svref type-info $gettable-variables-slot)
  1326. X                     settable-variable))
  1327. X             (setf (svref type-info $settable-variables-slot)
  1328. X                    (add-to-set
  1329. X                     (svref type-info $settable-variables-slot)
  1330. X                     settable-variable))))))
  1331. X
  1332. X(defun parse-initable-option (var-names args type-info)
  1333. X
  1334. X; Example ARGS = (A B C D), NIL. Duplicate
  1335. X; variables specified are ignored.
  1336. X
  1337. X (dolist (initable-variable (or args var-names))
  1338. X
  1339. X         (if (member initable-variable var-names :test #'eq)
  1340. X
  1341. X         ; THEN This variable is a real instance variable.
  1342. X
  1343. X           (setf (svref type-info  $initable-variables-slot)
  1344. X                  (add-to-set
  1345. X                   (svref type-info $initable-variables-slot)
  1346. X
  1347. X                   initable-variable))
  1348. X         ; ELSE We have an          (svref type-info $initable-variables-serror
  1349. X            "variable '~S' in the initable~% options list is not an instance variable.~%"
  1350. X            (type-name type-info)
  1351. X            initable-variable))))
  1352. X
  1353. X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1354. X; Parsing of :INIT-KEYWORDS Option and Suboption and :REDEFINED-METHODS
  1355. X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1356. X
  1357. X(defun parse-init-keywords-option (var-names args type-info)
  1358. X  (declare (ignore var-names))
  1359. X
  1360. X; Parses: (:INIT-KEYWORDS <symbol>).  Doesn't use VAR-NAMES.  By the
  1361. X; time this routine is called, each element of args has been checked to
  1362. X; be a symbol not equal to NIL.  ARGS is also a proper list. For
  1363. X; (:INIT-KEYWORDS), ARGS will be NIL.  We add the existing
  1364. X; init-keywords because we may have hit :INIT-KEYWORDS suboptions from
  1365. X; :INHERIT-FROM options.
  1366. X
  1367. X (setf (svref type-info $INIT-KEYWORDS-SLOT)
  1368. X        (add-to-set (svref type-info $INIT-KEYWORDS-SLOT) args)))
  1369. X
  1370. X(defun parse-no-init-keyword-check-option (var-names args type-info)
  1371. X  (declare (ignore args var-names))
  1372. X
  1373. X; Parses: :NO-INIT-KEYWORD-CHECK. VAR-NAMES is not used.
  1374. X
  1375. X (setf (svref type-info $NO-INIT-KEYWORD-CHECK-SLOT) t))
  1376. X
  1377. X(defun parse-redefined-methods-option (var-names args type-info)
  1378. X
  1379. X  (declare (ignore var-names))
  1380. X
  1381. X; Parses: (:REDEFINED-METHODS M1 M2 M3), or (:REDEFINED-METHODS).  ARGS
  1382. X; = (M1 M2 M3).  At this point, ARGS is guaranteed to be a proper list
  1383. X; where each element is a symbol that is non-NIL.  For
  1384. X; (:REDEFINED-METHODS), args is NIL.  NOTE: The order of arguments are
  1385. X; stored away doesn't matter.
  1386. X
  1387. X (setf (svref type-info $methods-to-not-define-slot)
  1388. X        (remove-duplicates args :test #'eq)))
  1389. X
  1390. X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1391. X; Parsing of :INHERIT-FROM Option and Suboption
  1392. X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1393. X
  1394. X(defun parse-inherit-from-option (var-names args type-info)
  1395. X  (declare (ignore var-names))
  1396. X
  1397. X; ARGS is the list of remaining stuff inside the :INHERIT-FROM option.
  1398. X; We know that ARGS is a proper list and that it has at least one element.
  1399. X; Sample: ARGS = (PARENT1 (:METHODS M1 M2 M3)
  1400. X;                         (:VARIABLES X Y Z)
  1401. X;                         (:INIT-KEYWORDS :EXCEPT Q))
  1402. X; VAR-NAMES is not used.  Note that for error handling to be changed to
  1403. X; continuable errors, these options will have to be changed, since side
  1404. X; effects to type info can occur before a syntax error occurs.  When
  1405. X; finished, the $PARENT-TYPES-SLOT and the $PARENTS-INFO-SLOT may be
  1406. X; changed.
  1407. X
  1408. X (if (and (consp args) (symbolp (car args))) 
  1409. X
  1410. X ; THEN The form of the parent is ok.
  1411. X ;      Now check if it is partially defined.
  1412. X
  1413. X   (let ((parent-type-info (type-partially-defined? (car args)))
  1414. X         (parents (svref type-info $PARENT-TYPES-SLOT))
  1415. X         (new-parent (car args)))
  1416. X
  1417. X     (if (not parent-type-info)
  1418. X
  1419. X     ; THEN The parent isn't defined.  Give an error.
  1420. X
  1421. X       (co-deftype-error
  1422. X        "~%the parent '~s',~s of the :INHERIT-FROM option, is not defined."
  1423. X        (type-name type-info)
  1424. X        new-parent)
  1425. X     
  1426. X     ; ELSE The parent is partially defined.
  1427. X     ;      First check that options specified are ok.
  1428. X     ; Add the parent to the type-info slot.  We must append
  1429. X     ; since the order is important -- the first :INHERIT-FROM option
  1430. X     ; must be the first parent.
  1431. X     ; Check that we don't have something like:
  1432. X     ;      (INHERIT-FROM B...)
  1433. X     ;      (INHERIT-FROM B...) within the type definition.
  1434. X       (if
  1435. X         (member new-parent parents :test #'eq)
  1436. X
  1437. X       ; THEN Two or more parents that are the same parent.
  1438. X
  1439. X         (co-deftype-error
  1440. X          "~~Sarent '~s' of type '~s'~s can only be a parent once."
  1441. X          (type-name type-info)
  1442. X          new-parent
  1443. X          (type-name type-info))
  1444. X
  1445. X       ; ELSE Everything is ok.
  1446. X       ; Add the parents type-info to be used later.
  1447. X       ; This is stored in the same order as the parents in the
  1448. X       ; $PARENT-TYPES-SLOT for consistency.
  1449. X       
  1450. X         (progn
  1451. X           (set-parents-info
  1452. X            type-info
  1453. X            (append (get-parents-info type-info)
  1454. X                    (list
  1455. X                      (list new-parent parent-type-info '*place-holder*))))
  1456. X           (setf (svref type-info $PARENT-TYPES-SLOT)
  1457. X                  (append parents (list new-parent)))
  1458. X           (parse-inherit-from-suboptions
  1459. X            type-info
  1460. X            parent-type-info
  1461. X            (cdr args))))))
  1462. X
  1463. X ; ELSE The parent form is illegal.
  1464. X
  1465. X   (co-deftype-error
  1466. X    "~%a symbol must follow an :INHERIT-FROM~% option."
  1467. X    (type-name type-info))))
  1468. X
  1469. X(defun parse-inherit-from-suboptions
  1470. X (type-info parent-type-info suboptions)
  1471. X
  1472. X; It is legal for SUBOPTIONS to be NIL.  For understandibility,
  1473. X; expandability, and consistancy the parsing of subptions uses the same
  1474. X; techniques with the same keywords for option information.  This is
  1475. X; true even though some of the option information may not be shared
  1476. X; between options and suboptions.  See CO-PARSE-OPTIONS and its
  1477. X; constituent routines.  NOTE: If the name of :METHODS option is ever
  1478. X; changed (in RETURN-OPTION-INFO) the references to :METHODS must be
  1479. X; changed here as well.
  1480. X;
  1481. X; Example: SUBOPTIONS = ((:VARIABLES A B)
  1482. X;                        (:METHODS C D)
  1483. X;                        (:INIT-KEYWORDS EXCEPT J))
  1484. X
  1485. X (let ((suboptions-so-far nil)
  1486. X       (suboption-name nil)
  1487. X       (suboption-info nil))
  1488. X
  1489. X   (dolist (suboption suboptions)
  1490. X
  1491. X   ; SUBOPTION-INFO will be NIL if SUBOPTION-NAME is not a
  1492. X   ; legal suboption, or a list of information that tells what
  1493. X   ; characteristics this suboption has.  Note that currently,
  1494. X   ; if an error occurs in SUBOPTON-OK? we will NOT return
  1495. X   ; to this function. The check for (WHEN SUBOPTION-INFO...)
  1496. X   ; is for future continuable errors. If 'ONCE' is on this
  1497. X   ; list, it means the suboption can only occur once.
  1498. X
  1499. X           (multiple-value-setq (suboption-name suboption-info)
  1500. X                (option-ok?
  1501. X                 suboption
  1502. X                 type-info
  1503. X                 'inherit-from-suboption))
  1504. X           (when suboption-info
  1505. X
  1506. X           ; THEN The suboption is a real one.
  1507. X           ;      Now make sure it doesn't occur more then once.
  1508. X
  1509. X             (if
  1510. X               (and (member suboption-name suboptions-so-far :test #'eq)
  1511. X                    (member 'once (cdr suboption-info) :test #'eq))
  1512. X
  1513. X             ; THEN We have duplicate suboptions.  Give an error.
  1514. X
  1515. X               (co-deftype-error
  1516. X                "duplicate suboption,~s '~s',~s specified to :INHERIT-FROM option."
  1517. X                (type-name type-info)
  1518. X                suboption)
  1519. X
  1520. X             ; ELSE Everything is ok.
  1521. X
  1522. X               (progn
  1523. X                 (setf suboptions-so-far
  1524. X                        (cons suboption-name suboptions-so-far))
  1525. X                 (parse-inherit-from-suboption
  1526. X                  type-info
  1527. X                  parent-type-info
  1528. X                  suboption
  1529. X                  suboption-info)))))
  1530. X
  1531. X ; Now check the one funny case: If the :METHODS option was NOT present.
  1532. X
  1533. X   (unless (member ':methods suboptions-so-far :test #'eq)
  1534. X
  1535. X   ; THEN We had no :METHODS suboption, so inherit all methods
  1536. X   ;      (but not universal methods).  Do this by making
  1537. X   ;      a suboption (:METHODS :EXCEPT), and having it parsed.
  1538. X
  1539. X     (multiple-value-setq (suboption-name suboption-info)
  1540. X                    (option-ok?
  1541. X                     '(:methods :except)
  1542. X                     type-info
  1543. X                     'inherit-from-suboption))
  1544. X
  1545. X     (parse-inherit-from-suboption
  1546. X      type-info
  1547. X      parent-type-info
  1548. X      '(:methods :except)
  1549. X      suboption-info))))
  1550. X
  1551. X(defun parse-inherit-from-suboption
  1552. X (type-info parent-type-info suboption suboption-info)
  1553. X
  1554. X; Example: SUBOPTION = (:INIT-KEYWORDS :EXCEPT J K L) The suboption
  1555. X; given is either a symbol or a list.  When a list, the rest of the
  1556. X; arguments will be passed to the function (may be NIL).  If a symbol,
  1557. X; NIL is passed as arguments.
  1558. X
  1559. X (apply (car suboption-info)
  1560. X        (list type-info
  1561. X              parent-type-info
  1562. X              (if (consp suboption) (cdr suboption) nil))))
  1563. X
  1564. X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1565. X; Method Definition
  1566. X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1567. X
  1568. X(defun co-parse-method-macro-call
  1569. X (spec argument-list body)
  1570. X
  1571. X; Make sure that the type-name and method-name are ok.  Also, that the
  1572. X; call is a proper list. 
  1573. X; Note that use of instance variable names as formal
  1574. X; parameter names to the method and use of SELF as a formal parameter
  1575. X; name are not checked.
  1576. X
  1577. X  (let
  1578. X    (
  1579. X      (type-name NIL)
  1580. X      (method-name NIL)
  1581. X    )
  1582. X
  1583. X   ; Check to be sure the body is a proper list or NIL
  1584. X
  1585. X   (unless (or (null body) (proper-list body))
  1586. X
  1587. X   ; THEN the method definition is not a proper list
  1588. X
  1589. X     (define-method-error
  1590. X      "The call,~% '(DEFINE-METHOD ~S ~S ~S)',~% is missing arguments or is an improper list."
  1591. X      spec argument-list body))
  1592. X
  1593. X ; Check the spec
  1594. X
  1595. X   (unless (and (proper-list spec) (= (length spec) 2)) ;rds 3/8 eq->=
  1596. X
  1597. X   ; THEN The form of the (type-name method-name) is incorrect.
  1598. X
  1599. X     (define-method-error
  1600. X      "The type-name and method-name in the call,~% '(DEFINE-METHOD ~S ~S ~S)',~% must be a two element proper list."
  1601. X      spec argument-list body))
  1602. X
  1603. X   (setf method-name (second spec))
  1604. X   (setf type-name (first spec))
  1605. X   (unless (co-legal-type-or-method-name type-name)
  1606. X
  1607. X   ; THEN Invalid type.
  1608. X
  1609. X     (define-method-error
  1610. X      "Type name '~S' in the call,~% '(DEFINE-METHOD ~S ~S ~S)',~% must be a non-NIL symbol."
  1611. X      type-name
  1612. X      spec
  1613. X      argument-list
  1614. X      body))
  1615. X
  1616. X   (unless (co-legal-type-or-method-name method-name)
  1617. X
  1618. X   ; THEN Invalid method.
  1619. X
  1620. X     (define-method-error
  1621. X      "Method name '~S' in the call,~% '(DEFINE-METHOD ~S ~S ~S)',~% must be a non-NIL symbol."
  1622. X      method-name
  1623. X      spec
  1624. X      argument-list
  1625. X      body))
  1626. X
  1627. X ; Check that the argument-list is indeed a list.
  1628. X
  1629. X   (unless (or (null argument-list) (proper-list argument-list))
  1630. X     (define-method-error
  1631. X      "The argument list in the call,~% '(DEFINE-METHOD ~S ~S ~S)',~%  is missing or must be a proper list."
  1632. X      spec
  1633. X      argument-list
  1634. X      body))
  1635. X
  1636. X  ) ;let
  1637. X) ;co-parse-method-macro-call 
  1638. X
  1639. X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1640. X; Call-Method Support
  1641. X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1642. X
  1643. X(defun co-parse-call-to-method (call-method-call which-func class-name)
  1644. X
  1645. X; Parse a call to a CALL-METHOD or APPLY-METHOD. Signal any
  1646. X; errors in syntax.
  1647. X; 'which-func' is either "CALL-METHOD" or "APPLY-METHOD".
  1648. X
  1649. X (let ((method-name nil)
  1650. X       (rest-of-call call-method-call))
  1651. X   (setf rest-of-call (cdr rest-of-call))
  1652. X ; This should now be the list of arguments 
  1653. X
  1654. X   (unless (proper-list rest-of-call)
  1655. X
  1656. X   ; THEN The call to CALL-METHOD is not a proper list.
  1657. X
  1658. X     (error
  1659. X      (format nil
  1660. X              "~A: The call,~% '~S',~% is missing arguments or is an improper list."
  1661. X              which-func
  1662. X              call-method-call)))
  1663. X
  1664. X   ; If the form is APPLY-METHOD, check to be sure the argument list is
  1665. X   ; not NIl
  1666. X
  1667. X   (when (equalp which-func "APPLY-METHOD")
  1668. X     (unless (cadr rest-of-call)
  1669. X         
  1670. X       (error
  1671. X         (format nil
  1672. X             "APPLY-METHOD: The call,~% '~S',~% has no argument list."
  1673. X                 call-method-call
  1674. X         )
  1675. X       )
  1676. X     )
  1677. X   )
  1678. X
  1679. X   (setf method-name (first rest-of-call))
  1680. X   (cond
  1681. X     ((co-legal-type-or-method-name method-name)
  1682. X
  1683. X     ; THEN We have the local form of call-method (i.e.,
  1684. X     ;      (CALL-METHOD MOOSE 3) ) so just return.
  1685. X
  1686. X      NIL
  1687. X     )
  1688. X
  1689. X     ; ELSE Check if a two element list, each element a symbol.
  1690. X
  1691. X    ((consp method-name)
  1692. X     (unless
  1693. X       (and (= (length method-name) 2)
  1694. X            (proper-list method-name)
  1695. X            (co-legal-type-or-method-name (first method-name))
  1696. X            (co-legal-type-or-method-name (second method-name))
  1697. X            (co::legal-parent-p class-name (first method-name)))
  1698. X
  1699. X     ; Incorrect parent form of call-method.
  1700. X
  1701. X       (error
  1702. X        (format nil
  1703. X                "~A: Illegal parent reference '~S' in~% '~S'.~%  Must have the form: '(type-symbol operation-symbol)'."
  1704. X                which-func
  1705. X                method-name
  1706. X                call-method-call)
  1707. X      ))
  1708. X    )       
  1709. X
  1710. X    ; Anything else is an error.
  1711. X
  1712. X    (t
  1713. X      (error
  1714. X       (format nil
  1715. X               "~A: Incorrect form '~S' in~% '~S'.~%  Expecting non-NIL symbol or list or two non-NIL symbols."
  1716. X               which-func
  1717. X               method-name
  1718. X               call-method-call))))
  1719. X
  1720. X    ) ;let
  1721. X
  1722. X) ;co-parse-call-to-method
  1723. X
  1724. X(defun check-that-method-to-call-exists
  1725. X (possible-method-name child-name parent-name parent-methods)
  1726. X
  1727. X; Return the name of the method we will be calling.
  1728. X; The method name to use is determined as follows: First, always use the ':'
  1729. X; version of the name.  If the method with this name is not defined,
  1730. X; check if the name without the ':' is defined.  If it is, issue a
  1731. X; warning message that we are calling this method.  If it isn't
  1732. X; defined, issue a warning message that the method is not defined and
  1733. X; that we will call the ':' version when it is defined.  For example,
  1734. X; if we had the POSSIBLE-METHOD-NAME of A we would first check if a
  1735. X; method named :A existed in the PARENT-METHODS.  If it does, we
  1736. X; return :A.  If it doesn't, we see if a method with the name A
  1737. X; exists.  If it does, we return this name and give a warning.  If it
  1738. X; doesn't, we return :A and give a warning.
  1739. X
  1740. X (let*
  1741. X   ((method-to-call
  1742. X     (return-keyword-from-variable possible-method-name))
  1743. X    (saved-method-to-call method-to-call))
  1744. X
  1745. X   (unless (assoc method-to-call parent-methods :test #'eq)
  1746. X
  1747. X   ; THEN The ':' version of the method doesn't exist.
  1748. X   ;      Now check if the non-colon version exists.
  1749. X
  1750. X     (setf method-to-call possible-method-name)
  1751. X
  1752. X     (if
  1753. X       (assoc method-to-call parent-methods :test #'eq)
  1754. X
  1755. X     ; THEN We are calling the non-colon version of the method.
  1756. X     ;      Give a warning message.
  1757. X
  1758. X       (warn
  1759. X         (format nil
  1760. X                 "DEFINE-TYPE: In type, '~A', '~A' of :VARIABLES suboption, will reference the parent method '~A'."
  1761. X                 child-name
  1762. X                 possible-method-name
  1763. X                 possible-method-name))
  1764. X
  1765. X     ; ELSE Give a warning that we will assume calling the ':' version.
  1766. X
  1767. X       (progn (setf method-to-call saved-method-to-call)
  1768. X              (warn
  1769. X                (format nil
  1770. X                        "DEFINE-TYPE: In type, '~A', '~A' of :VARIABLES suboption, has no corresponding method defined in parent '~A'. Will assume you want to call method '~A'."
  1771. X                        child-name
  1772. X                        possible-method-name
  1773. X                        parent-name
  1774. X                        method-to-call)))))
  1775. X   method-to-call))
  1776. X
  1777. X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1778. X
  1779. END_OF_FILE
  1780. if test 56836 -ne `wc -c <'co-parse.l'`; then
  1781.     echo shar: \"'co-parse.l'\" unpacked with wrong size!
  1782. fi
  1783. # end of 'co-parse.l'
  1784. fi
  1785. echo shar: End of archive 13 \(of 13\).
  1786. cp /dev/null ark13isdone
  1787. MISSING=""
  1788. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 ; do
  1789.     if test ! -f ark${I}isdone ; then
  1790.     MISSING="${MISSING} ${I}"
  1791.     fi
  1792. done
  1793. if test "${MISSING}" = "" ; then
  1794.     echo You have unpacked all 13 archives.
  1795.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1796. else
  1797.     echo You still need to unpack the following archives:
  1798.     echo "        " ${MISSING}
  1799. fi
  1800. ##  End of shell archive.
  1801. exit 0
  1802. -- 
  1803.  
  1804. Rich $alz            "Anger is an energy"
  1805. Cronus Project, BBN Labs    rsalz@bbn.com
  1806. Moderator, comp.sources.unix    sources@uunet.uu.net
  1807.